home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
system
/
interc2.zip
/
INTERPRE.C
< prev
next >
Wrap
Text File
|
1987-08-02
|
6KB
|
230 lines
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <dir.h>
#include "intercep.h"
#define MAXFILESIZE 20000 /* maximum template file size */
#define MAXLINELEN 200 /* maximum output line length */
#define AVGLINELEN 40 /* average line length */
char template_text[ MAXFILESIZE ]; /* file text */
char *templates[ MAXFILESIZE/AVGLINELEN ]; /* pointers to each line */
int ntemplates; /* number of templates */
/* copy template to dest, changing regname to regval throughout.
* assumes dest is big enough to hold result.
*/
void
subst(char *regname, unsigned rval, char *template, char *dest)
{
char regval[5];
if (regname[1] == 'H' || regname[1] == 'L')
sprintf(regval, "%02X", rval);
else
sprintf(regval, "%04X", rval);
while (*dest = *template) { /* copy through '\0' at end of string. */
if (template[0] == regname[0] && template[1] == regname[1]) {
dest = stpcpy(dest, regval);
template += 2; /* all regnames are 2 chars long */
}
else {
template++;
dest++;
}
}
}
/* Read template file into buffer, setting pointers to
* beginning of lines.
* Sets template_text, templates and ntemplates.
* Pads out interrupt IDs to 6 characters.
* Returns number of lines.
*/
int
read_template_file(char *filename)
{
FILE *ifile;
char inline[ MAXLINELEN ];
char **nextline = templates;
char *dest = template_text;
char *q = template_text;
if (! (ifile = fopen(filename, "rt")))
return 0;
while (fgets(inline, MAXLINELEN, ifile)) {
char *p = inline;
if (! isxdigit(inline[0]))
continue; /* handle comment lines */
*nextline++ = dest = q;
while (isxdigit(*p))
*q++ = *p++; /* copy initial hex string */
while (q < dest+6)
*q++ = ' '; /* pad out to 6 characters */
*p = ' '; /* convert tab (or whatever) to space */
while (*q++ = *p++)
; /* copy rest of line through null */
while (q[-3] == '\\' && q[-2] == '\n') { /* continuation lines */
if (p = fgets(inline, MAXLINELEN, ifile)) {
q -= 3;
*q++ = '\n';
while (*q++ = *p++)
;
}
else
goto on_eof;
}
}
on_eof:
*nextline = NULL;
return (ntemplates = nextline - templates);
}
int compare_templates(char **t1, char **t2)
{
return(strnicmp(*t1, *t2, 6));
}
/* find a matching template given interrupt number and ax value
* works from the most specific (all 6 characters)
* back to the most general (just the 2 characters of the interrupt number).
*/
char *find_template(int intnum, unsigned axval)
{
char proposed[ 7 ];
char *key = proposed;
char **found;
char *ignoring = proposed + 6;
sprintf(proposed, "%02X%04X", intnum, axval);
while (ignoring > proposed) {
if (found = bsearch(&key, templates, ntemplates,
sizeof(char *), compare_templates))
return(*found);
/* else ignore 2 more characters */
ignoring -= 2;
ignoring[0] = ignoring[1] = ' ';
}
return NULL;
}
#define HI(u) (((u)&0xff00)>>8)
#define LO(u) ((u)&0x00ff)
/* read Swi_info records from input file
* interpret them, and output to output file.
*/
void
interpret_file(FILE *ifp, FILE *ofp, char *progname, int longmode)
{
Swi_info rec;
char s1[ MAXLINELEN ];
char s2[ MAXLINELEN ];
char *templ;
if (progname != NULL)
fprintf (ofp, "INTERCEPT/INTERPRET by Ned Konz 08/02/87\n"
"dump of DOS/BIOS calls from program \"%s\"\n",
progname);
if (longmode)
fprintf(ofp,
" CS:IP INT AX BX CX DX DS ES SI DI BP\n");
while (fread(&rec, sizeof(Swi_info), 1, ifp)) {
if (templ = find_template(rec.intnum, rec.regs.ovl.old[2])) {
subst("AX", rec.regs.ovl.old[2], templ, s1);
subst("AH", HI(rec.regs.ovl.old[2]), s1, s2);
subst("AL", LO(rec.regs.ovl.old[2]), s2, s1);
subst("BX", rec.regs.ovl.old[1], s1, s2);
subst("BH", HI(rec.regs.ovl.old[1]), s2, s1);
subst("BL", LO(rec.regs.ovl.old[1]), s1, s2);
subst("CX", rec.regs.ovl.old[0], s2, s1);
subst("CH", HI(rec.regs.ovl.old[0]), s1, s2);
subst("CL", LO(rec.regs.ovl.old[0]), s2, s1);
subst("DX", rec.regs.dx, s1, s2);
subst("DH", HI(rec.regs.dx), s2, s1);
subst("DL", LO(rec.regs.dx), s1, s2);
subst("BP", rec.regs.bp, s2, s1);
subst("DI", rec.regs.di, s1, s2);
subst("SI", rec.regs.si, s2, s1);
subst("DS", rec.regs.ds, s1, s2);
subst("ES", rec.regs.es, s2, s1);
subst("CS", FP_SEG(rec.caller.ipcs), s1, s2);
subst("IP", FP_OFF(rec.caller.ipcs), s2, s1);
fprintf(ofp, "%Fp %s",
(char far *)rec.caller.ipcs - 2, s1);
}
if ((templ==NULL) || longmode) {
fprintf(ofp,
"%Fp %2x %04x "
"%04x %04x %04x "
"%04x %04x %04x %04x %04x\n",
(char far *)rec.caller.ipcs - 2, rec.intnum,
rec.regs.ovl.old[2], /*AX*/
rec.regs.ovl.old[1] /*BX*/, rec.regs.ovl.old[0],/*CX*/ rec.regs.dx,
rec.regs.ds, rec.regs.es, rec.regs.si, rec.regs.di,
rec.regs.bp);
}
} /*while*/
return;
}
int
main(int argc, char *argv[])
{
int longmode = 0;
char *templfile = TFILENAME;
char *progname = argv[0];
FILE *ifp, *ofp;
if (argc < 3) {
fprintf(stderr, "INTERCEPT/INTERPRET by Ned Konz 08/02/87\n"
"usage: %s [-l] [-t templ_file] "
"infile outfile [progname]\n",
argv[0]);
exit(1);
}
argv++;
while (argv[0][0] == '-') {
if (! stricmp(argv[0], "-l")) { longmode++; }
else if (! stricmp(argv[0], "-t")) { templfile = argv[1]; argv++; }
else {
fprintf(stderr, "%s: unknown switch \"%s\"\n", progname, argv[0]);
exit(4);
}
argv++;
}
if (! read_template_file( searchpath(templfile) )) {
fprintf(stderr, "%s: error during read of \"%s\"\n",
progname, templfile);
exit(5);
}
qsort(templates, ntemplates, sizeof(char *), compare_templates);
if (! (ifp = fopen(argv[0], "rb"))) {
fprintf(stderr, "%s: can't open input file \"%s\"\n",
progname, argv[0]);
exit(2);
}
if (! (ofp = fopen(argv[1], "wt"))) {
fprintf(stderr, "%s: can't open output file \"%s\"\n",
progname, argv[1]);
exit(3);
}
interpret_file(ifp, ofp, argv[2], longmode);
fclose(ifp);
fclose(ofp);
exit(0);
}